<!DOCTYPE html>
<html lang="zh-CN" data-theme="light">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="generator" content="VuePress 2.0.0-beta.53" />
    <meta name="theme" content="VuePress Theme Hope" />
    <link rel="icon" href="/doc/images/favicon.ico"><title>提供者 | AT 的文档库</title><meta name="description" content="At 的文档库，好记性不如烂笔头！">
    <style>
      :root {
        --bg-color: #fff;
      }

      html[data-theme="dark"] {
        --bg-color: #1d2025;
      }

      html,
      body {
        background: var(--bg-color);
      }
    </style>
    <script>
      const userMode = localStorage.getItem("vuepress-theme-hope-scheme");
      const systemDarkMode =
        window.matchMedia &&
        window.matchMedia("(prefers-color-scheme: dark)").matches;

      if (userMode === "dark" || (userMode !== "light" && systemDarkMode)) {
        document.querySelector("html").setAttribute("data-theme", "dark");
      }
    </script>
    <link rel="preload" href="/doc/assets/style.c3a4c10b.css" as="style" /><link rel="stylesheet" href="/doc/assets/style.c3a4c10b.css" />
    <link rel="modulepreload" href="/doc/assets/app.41440b49.js"><link rel="modulepreload" href="/doc/assets/Providers.html.9bef3753.js"><link rel="modulepreload" href="/doc/assets/_plugin-vue_export-helper.cdc0426e.js"><link rel="modulepreload" href="/doc/assets/Providers.html.7d2793f1.js"><link rel="prefetch" href="/doc/assets/index.html.0bcc895f.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.c8df2167.js" as="script" /><link rel="prefetch" href="/doc/assets/Vue2.html.48e096c5.js" as="script" /><link rel="prefetch" href="/doc/assets/Vue3.html.324e646c.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.fb0ad0e0.js" as="script" /><link rel="prefetch" href="/doc/assets/第 1 章 导言.html.d6c662f8.js" as="script" /><link rel="prefetch" href="/doc/assets/第 2 章 TypeScript 概述.html.e976154a.js" as="script" /><link rel="prefetch" href="/doc/assets/第 3 章 类型全解.html.e4f1b931.js" as="script" /><link rel="prefetch" href="/doc/assets/第 4 章 函数.html.701a2968.js" as="script" /><link rel="prefetch" href="/doc/assets/第 5 章 类和接口.html.8988d546.js" as="script" /><link rel="prefetch" href="/doc/assets/第 6 章 类型进阶.html.45b313e3.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.a9dd6465.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.a3374cf8.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.c326eaaf.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.88582229.js" as="script" /><link rel="prefetch" href="/doc/assets/常见问题.html.e0f65550.js" as="script" /><link rel="prefetch" href="/doc/assets/扩展使用.html.87cccc41.js" as="script" /><link rel="prefetch" href="/doc/assets/掌握 GIT.html.c150b234.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.a3c2858b.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.9a53d157.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.101afd82.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.8224e1cd.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.54b5ca2d.js" as="script" /><link rel="prefetch" href="/doc/assets/基础掌握.html.d839cc53.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.80e4d5cc.js" as="script" /><link rel="prefetch" href="/doc/assets/基础掌握.html.9a178a04.js" as="script" /><link rel="prefetch" href="/doc/assets/扩展知识.html.3535ab30.js" as="script" /><link rel="prefetch" href="/doc/assets/项目搭建.html.e926587b.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.881e95b0.js" as="script" /><link rel="prefetch" href="/doc/assets/安装及使用.html.ba7314a3.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.f9509ce0.js" as="script" /><link rel="prefetch" href="/doc/assets/第 1 章.html.726a0bb9.js" as="script" /><link rel="prefetch" href="/doc/assets/第 2 章.html.38f55e7d.js" as="script" /><link rel="prefetch" href="/doc/assets/Controllers.html.6b27764c.js" as="script" /><link rel="prefetch" href="/doc/assets/Module.html.3849b10b.js" as="script" /><link rel="prefetch" href="/doc/assets/404.html.c5de7dd9.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.86b08b0b.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.f4119260.js" as="script" /><link rel="prefetch" href="/doc/assets/Vue2.html.caf7eb18.js" as="script" /><link rel="prefetch" href="/doc/assets/Vue3.html.6dc23cf4.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.868f2c80.js" as="script" /><link rel="prefetch" href="/doc/assets/第 1 章 导言.html.9edf000e.js" as="script" /><link rel="prefetch" href="/doc/assets/第 2 章 TypeScript 概述.html.76b27e4d.js" as="script" /><link rel="prefetch" href="/doc/assets/第 3 章 类型全解.html.9ad8a3d4.js" as="script" /><link rel="prefetch" href="/doc/assets/第 4 章 函数.html.9115df00.js" as="script" /><link rel="prefetch" href="/doc/assets/第 5 章 类和接口.html.e392a0d1.js" as="script" /><link rel="prefetch" href="/doc/assets/第 6 章 类型进阶.html.1b5b864e.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.e5a75968.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.974654cf.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.ed3fa7a3.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.3b9ebcaa.js" as="script" /><link rel="prefetch" href="/doc/assets/常见问题.html.b427e39a.js" as="script" /><link rel="prefetch" href="/doc/assets/扩展使用.html.76b3dd90.js" as="script" /><link rel="prefetch" href="/doc/assets/掌握 GIT.html.724416fc.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.8b55f9ef.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.8ee968a7.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.06371751.js" as="script" /><link rel="prefetch" href="/doc/assets/面试题详解.html.6b672044.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.b200eaff.js" as="script" /><link rel="prefetch" href="/doc/assets/基础掌握.html.5135d2c4.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.557b7bf5.js" as="script" /><link rel="prefetch" href="/doc/assets/基础掌握.html.7b535b09.js" as="script" /><link rel="prefetch" href="/doc/assets/扩展知识.html.c6b233af.js" as="script" /><link rel="prefetch" href="/doc/assets/项目搭建.html.450f0b1d.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.6483ed06.js" as="script" /><link rel="prefetch" href="/doc/assets/安装及使用.html.b4d859f3.js" as="script" /><link rel="prefetch" href="/doc/assets/index.html.f15cf3e9.js" as="script" /><link rel="prefetch" href="/doc/assets/第 1 章.html.127b1e7c.js" as="script" /><link rel="prefetch" href="/doc/assets/第 2 章.html.ea8e67e2.js" as="script" /><link rel="prefetch" href="/doc/assets/Controllers.html.029df1e7.js" as="script" /><link rel="prefetch" href="/doc/assets/Module.html.f102db2a.js" as="script" /><link rel="prefetch" href="/doc/assets/404.html.2cfd6b20.js" as="script" /><link rel="prefetch" href="/doc/assets/photoswipe.esm.09e03fed.js" as="script" />
  </head>
  <body>
    <div id="app"><!--[--><!--[--><!--[--><span tabindex="-1"></span><a href="#main-content" class="skip-link sr-only">Skip to content</a><!--]--><div class="theme-container has-toc"><!--[--><!--[--><header class="navbar"><div class="navbar-left"><button class="toggle-sidebar-button" title="Toggle Sidebar"><span class="icon"></span></button><!--[--><!----><!--]--><a href="/doc/" class="brand"><!----><!----><span class="site-name">AT 的文档库</span></a><!--[--><!----><!--]--></div><div class="navbar-center"><!--[--><!----><!--]--><nav class="nav-links"><div class="nav-item hide-in-mobile"><a href="/doc/" class="nav-link" aria-label="首页"><!---->首页<!----></a></div><div class="nav-item hide-in-mobile"><div class="dropdown-wrapper"><button class="dropdown-title" type="button" aria-label="开发问题汇总"><span class="title"><!---->开发问题汇总</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a href="/doc/development-question/Vue" class="nav-link" aria-label="Vue"><!---->Vue<!----></a></li></ul></button></div></div><div class="nav-item hide-in-mobile"><div class="dropdown-wrapper"><button class="dropdown-title" type="button" aria-label="系统笔记"><span class="title"><!---->系统笔记</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a href="/doc/sysnotes/Git/%E6%8E%8C%E6%8F%A1%20GIT.html" class="nav-link" aria-label="GIT"><!---->GIT<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/Nvm/%E5%AE%89%E8%A3%85%E5%8F%8A%E4%BD%BF%E7%94%A8.html" class="nav-link" aria-label="NVM"><!---->NVM<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/Linux/%E5%9F%BA%E7%A1%80%E6%8E%8C%E6%8F%A1.html" class="nav-link" aria-label="Linux"><!---->Linux<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/JavaScript" class="nav-link" aria-label="JavaScript"><!---->JavaScript<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/CSS" class="nav-link" aria-label="CSS"><!---->CSS<!----></a></li><li class="dropdown-item"><a href="/doc/sysnotes/HTML" class="nav-link" aria-label="HTML"><!---->HTML<!----></a></li></ul></button></div></div><div class="nav-item hide-in-mobile"><div class="dropdown-wrapper"><button class="dropdown-title" type="button" aria-label="阅读笔记"><span class="title"><!---->阅读笔记</span><span class="arrow"></span><ul class="nav-dropdown"><li class="dropdown-item"><a href="/doc/readbook/《Vue.js 设计与实现》/" class="nav-link" aria-label="《Vue.js 设计与实现》"><!---->《Vue.js 设计与实现》<!----></a></li><li class="dropdown-item"><a href="/doc/readbook/《TypeScript 编程》/" class="nav-link" aria-label="《TypeScript 编程》"><!---->《TypeScript 编程》<!----></a></li></ul></button></div></div></nav><!--[--><!----><!--]--></div><div class="navbar-right"><!--[--><!----><!--]--><div class="nav-item hide-in-mobile"><button id="appearance-switch"><svg xmlns="http://www.w3.org/2000/svg" class="icon auto-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="auto icon" style="display:block;"><path d="M512 992C246.92 992 32 777.08 32 512S246.92 32 512 32s480 214.92 480 480-214.92 480-480 480zm0-840c-198.78 0-360 161.22-360 360 0 198.84 161.22 360 360 360s360-161.16 360-360c0-198.78-161.22-360-360-360zm0 660V212c165.72 0 300 134.34 300 300 0 165.72-134.28 300-300 300z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon dark-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="dark icon" style="display:none;"><path d="M524.8 938.667h-4.267a439.893 439.893 0 0 1-313.173-134.4 446.293 446.293 0 0 1-11.093-597.334A432.213 432.213 0 0 1 366.933 90.027a42.667 42.667 0 0 1 45.227 9.386 42.667 42.667 0 0 1 10.24 42.667 358.4 358.4 0 0 0 82.773 375.893 361.387 361.387 0 0 0 376.747 82.774 42.667 42.667 0 0 1 54.187 55.04 433.493 433.493 0 0 1-99.84 154.88 438.613 438.613 0 0 1-311.467 128z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon light-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="light icon" style="display:none;"><path d="M952 552h-80a40 40 0 0 1 0-80h80a40 40 0 0 1 0 80zM801.88 280.08a41 41 0 0 1-57.96-57.96l57.96-58a41.04 41.04 0 0 1 58 58l-58 57.96zM512 752a240 240 0 1 1 0-480 240 240 0 0 1 0 480zm0-560a40 40 0 0 1-40-40V72a40 40 0 0 1 80 0v80a40 40 0 0 1-40 40zm-289.88 88.08-58-57.96a41.04 41.04 0 0 1 58-58l57.96 58a41 41 0 0 1-57.96 57.96zM192 512a40 40 0 0 1-40 40H72a40 40 0 0 1 0-80h80a40 40 0 0 1 40 40zm30.12 231.92a41 41 0 0 1 57.96 57.96l-57.96 58a41.04 41.04 0 0 1-58-58l58-57.96zM512 832a40 40 0 0 1 40 40v80a40 40 0 0 1-80 0v-80a40 40 0 0 1 40-40zm289.88-88.08 58 57.96a41.04 41.04 0 0 1-58 58l-57.96-58a41 41 0 0 1 57.96-57.96z"></path></svg></button></div><form class="search-box" role="search"><input type="search" autocomplete="off" spellcheck="false" value><!----></form><!--[--><!----><!--]--><button class="toggle-navbar-button" aria-label="Toggle Navbar" aria-expanded="false" aria-controls="nav-screen"><span class="button-container"><span class="button-top"></span><span class="button-middle"></span><span class="button-bottom"></span></span></button></div></header><!----><!--]--><!----><div class="toggle-sidebar-wrapper"><span class="arrow left"></span></div><aside class="sidebar"><!--[--><!----><!--]--><ul class="sidebar-links"><li><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">CSS</span><span class="arrow right"></span></button><!----></section></li><li><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">GIT</span><span class="arrow right"></span></button><!----></section></li><li><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">HTML</span><span class="arrow right"></span></button><!----></section></li><li><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">JavaScript</span><span class="arrow right"></span></button><!----></section></li><li><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">Linux</span><span class="arrow right"></span></button><!----></section></li><li><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">NestJs</span><span class="arrow right"></span></button><!----></section></li><li><section class="sidebar-group"><button class="sidebar-heading clickable"><!----><span class="title">NVM</span><span class="arrow right"></span></button><!----></section></li></ul><!--[--><!----><!--]--></aside><!--[--><main class="page" id="main-content"><!--[--><!----><nav class="breadcrumb disable"></nav><div class="page-title"><h1><!---->提供者</h1><div class="page-info"><!----><!----><span class="date-info" aria-label="写作日期📅" data-balloon-pos="down"><svg xmlns="http://www.w3.org/2000/svg" class="icon calendar-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="calendar icon"><path d="M716.4 110.137c0-18.753-14.72-33.473-33.472-33.473-18.753 0-33.473 14.72-33.473 33.473v33.473h66.993v-33.473zm-334.87 0c0-18.753-14.72-33.473-33.473-33.473s-33.52 14.72-33.52 33.473v33.473h66.993v-33.473zm468.81 33.52H716.4v100.465c0 18.753-14.72 33.473-33.472 33.473a33.145 33.145 0 01-33.473-33.473V143.657H381.53v100.465c0 18.753-14.72 33.473-33.473 33.473a33.145 33.145 0 01-33.473-33.473V143.657H180.6A134.314 134.314 0 0046.66 277.595v535.756A134.314 134.314 0 00180.6 947.289h669.74a134.36 134.36 0 00133.94-133.938V277.595a134.314 134.314 0 00-133.94-133.938zm33.473 267.877H147.126a33.145 33.145 0 01-33.473-33.473c0-18.752 14.72-33.473 33.473-33.473h736.687c18.752 0 33.472 14.72 33.472 33.473a33.145 33.145 0 01-33.472 33.473z"></path></svg><span>2023年2月19日</span><meta property="datePublished" content="2023-02-19T11:39:44.000Z"></span><!----><!----><span class="reading-time-info" aria-label="阅读时间⌛" data-balloon-pos="down"><svg xmlns="http://www.w3.org/2000/svg" class="icon timer-icon" viewBox="0 0 1024 1024" fill="currentColor" aria-label="timer icon"><path d="M799.387 122.15c4.402-2.978 7.38-7.897 7.38-13.463v-1.165c0-8.933-7.38-16.312-16.312-16.312H256.33c-8.933 0-16.311 7.38-16.311 16.312v1.165c0 5.825 2.977 10.874 7.637 13.592 4.143 194.44 97.22 354.963 220.201 392.763-122.204 37.542-214.893 196.511-220.2 389.397-4.661 5.049-7.638 11.651-7.638 19.03v5.825h566.49v-5.825c0-7.379-2.849-13.981-7.509-18.9-5.049-193.016-97.867-351.985-220.2-389.527 123.24-37.67 216.446-198.453 220.588-392.892zM531.16 450.445v352.632c117.674 1.553 211.787 40.778 211.787 88.676H304.097c0-48.286 95.149-87.382 213.728-88.676V450.445c-93.077-3.107-167.901-81.297-167.901-177.093 0-8.803 6.99-15.793 15.793-15.793 8.803 0 15.794 6.99 15.794 15.793 0 80.261 63.69 145.635 142.01 145.635s142.011-65.374 142.011-145.635c0-8.803 6.99-15.793 15.794-15.793s15.793 6.99 15.793 15.793c0 95.019-73.789 172.82-165.96 177.093z"></path></svg><span>大约 7 分钟</span><meta property="timeRequired" content="PT7M"></span></div><hr></div><div class="toc-place-holder"><aside id="toc"><div class="toc-header">此页内容</div><div class="toc-wrapper"><ul class="toc-list"><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#服务" class="router-link-active router-link-exact-active toc-link level2">服务</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#依赖注入" class="router-link-active router-link-exact-active toc-link level2">依赖注入</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#作用域" class="router-link-active router-link-exact-active toc-link level2">作用域</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#自定义提供者" class="router-link-active router-link-exact-active toc-link level2">自定义提供者</a></li><ul class="toc-list"><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#标准提供者" class="router-link-active router-link-exact-active toc-link level3">标准提供者</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#值提供者" class="router-link-active router-link-exact-active toc-link level3">值提供者</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#非类提供者" class="router-link-active router-link-exact-active toc-link level3">非类提供者</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#类提供者-useclass" class="router-link-active router-link-exact-active toc-link level3">类提供者（useClass）</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#工厂提供者-usefactory" class="router-link-active router-link-exact-active toc-link level3">工厂提供者（useFactory）</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#别名提供者-useexisting" class="router-link-active router-link-exact-active toc-link level3">别名提供者（useExisting）</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#非服务提供者" class="router-link-active router-link-exact-active toc-link level3">非服务提供者</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#导出自定义提供者" class="router-link-active router-link-exact-active toc-link level3">导出自定义提供者</a></li><!----><!--]--></ul><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#异步提供者" class="router-link-active router-link-exact-active toc-link level2">异步提供者</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#可选提供者" class="router-link-active router-link-exact-active toc-link level2">可选提供者</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#基于属性的注入" class="router-link-active router-link-exact-active toc-link level2">基于属性的注入</a></li><!----><!--]--><!--[--><li class="toc-item"><a aria-current="page" href="/doc/sysnotes/NestJs/%E6%A6%82%E8%BF%B0/Providers.html#注册提供者" class="router-link-active router-link-exact-active toc-link level2">注册提供者</a></li><!----><!--]--></ul></div></aside></div><!----><div class="theme-hope-content"><h1 id="提供者" tabindex="-1"><a class="header-anchor" href="#提供者" aria-hidden="true">#</a> 提供者</h1><p>Providers 是 Nest 的一个基本概念。许多基本的 Nest 类可能被视为 provider - <code>service, repository, factory, helper</code> 等等。 他们都可以通过 constructor 注入依赖关系。 这意味着对象可以彼此创建各种关系，并且“连接”对象实例的功能在很大程度上可以委托给 Nest运行时系统。 Provider 只是一个用 <code>@Injectable()</code> 装饰器注释的类。</p><p><img src="https://docs.nestjs.com/assets/Components_1.png" alt="Providers"></p><p>控制器应处理 HTTP 请求并将更复杂的任务委托给 providers。Providers 是纯粹的 JavaScript 类，在其类声明之前带有 <code>@Injectable()</code> 装饰器。</p><h2 id="服务" tabindex="-1"><a class="header-anchor" href="#服务" aria-hidden="true">#</a> 服务</h2><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> Injectable <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;@nestjs/common&#39;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Injectable</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">UserService</span> <span class="token punctuation">{</span>
  <span class="token keyword">private</span> <span class="token keyword">readonly</span> users<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>

  <span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>users
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p>使用 CLI 创建 <code>nest g service [name]</code></p></blockquote><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token doc-comment comment">/**
 * user.controller.ts
 */</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> Controller<span class="token punctuation">,</span> Get <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;@nestjs/common&#39;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> UserService <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./user.service&#39;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Controller</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">UserController</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token keyword">private</span> userService<span class="token operator">:</span> UserService<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

  <span class="token decorator"><span class="token at operator">@</span><span class="token function">Get</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>userService<span class="token punctuation">.</span><span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Service 是通过类构造函数注入的。这里使用了私有的只读语法。意味着已经在同一位置创建并初始化了 userService 成员。</p><h2 id="依赖注入" tabindex="-1"><a class="header-anchor" href="#依赖注入" aria-hidden="true">#</a> 依赖注入</h2><p>Nest 是建立在强大的设计模式，通常称为依赖注入。</p><p>在 Nest 中，借助 TypeScript 功能，管理依赖项非常容易，因为它们仅按类型进行解析。在下面的示例中，Nest 将 userService 通过创建并返回一个实例来解析 UserService（或者，在单例的正常情况下，如果现有实例已在其他地方请求，则返回现有实例）。解析此依赖关系并将其传递给控制器的构造函数（或分配给指定的属性）：</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token function">constructor</span><span class="token punctuation">(</span><span class="token keyword">private</span> <span class="token keyword">readonly</span> userService<span class="token operator">:</span>UserService<span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h2 id="作用域" tabindex="-1"><a class="header-anchor" href="#作用域" aria-hidden="true">#</a> 作用域</h2><p>Provider 通常具有与应用程序生命周期同步的生命周期（“作用域”）。在启动应用程序时，必须解析每个依赖项，因此必须实例化每个提供程序。同样，当应用程序关闭时，每个 provider 都将被销毁。但是，有一些方法可以改变 provider 生命周期的请求范围。</p><h2 id="自定义提供者" tabindex="-1"><a class="header-anchor" href="#自定义提供者" aria-hidden="true">#</a> 自定义提供者</h2><p>Nest 有一个内置的控制反转（&quot;IoC&quot;）容器，可以解决 providers 之间的关系。 此功能是上述依赖注入功能的基础，但要比上面描述的要强大得多。<code>@Injectable()</code> 装饰器只是冰山一角, 并不是定义 providers 的唯一方法。相反，可以使用普通值、类、异步或同步工厂。</p><p>首先定义一个提供者。<code>@Injectable()</code> 装饰器将 <code>CatsService</code> 类标记为提供者。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token doc-comment comment">/**
 * cats.service.ts
 */</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>Injectable<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;@netsjs/common&#39;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Injectable</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">CatsService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">private</span> <span class="token keyword">readonly</span> cats<span class="token operator">:</span><span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">[</span><span class="token punctuation">]</span>

  <span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>cats
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>然后将提供程序注入到控制类中：</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token doc-comment comment">/**
 * cats.controller.ts
 */</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>Get<span class="token punctuation">,</span>Controller<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;@nestjs/common&#39;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>CatsService<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./cats.service.ts&#39;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Controller</span></span><span class="token punctuation">(</span><span class="token string">&#39;cats&#39;</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">CatsController</span><span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token keyword">private</span> <span class="token keyword">readonly</span> catsService<span class="token operator">:</span>CatsService<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>

  <span class="token decorator"><span class="token at operator">@</span><span class="token function">Get</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>catsService<span class="token punctuation">.</span><span class="token function">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>最后在 <code>Nest IoC</code> 容器中注册程序：</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token doc-comment comment">/**
 * cats.modules.ts
 */</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span>Module<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;@nestjs/common&#39;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>CatsController<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./cats.controller.ts&#39;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>CatsService<span class="token punctuation">}</span>  <span class="token keyword">from</span> <span class="token string">&#39;./cats.service.ts&#39;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  controllers<span class="token operator">:</span><span class="token punctuation">[</span>CatsController<span class="token punctuation">]</span><span class="token punctuation">,</span>
  providers<span class="token operator">:</span><span class="token punctuation">[</span>CatsService<span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">CatsModule</span> <span class="token punctuation">{</span>

<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="标准提供者" tabindex="-1"><a class="header-anchor" href="#标准提供者" aria-hidden="true">#</a> 标准提供者</h3><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  controllers<span class="token operator">:</span><span class="token punctuation">[</span>CatsController<span class="token punctuation">]</span><span class="token punctuation">,</span>
  providers<span class="token operator">:</span><span class="token punctuation">[</span>CatsService<span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Providers 属性接收一个提供者数组。上述为简写形式，完成语法如下：</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code>providers<span class="token operator">:</span><span class="token punctuation">[</span>
  <span class="token punctuation">{</span>
    provider<span class="token operator">:</span>CatsService<span class="token punctuation">,</span>
    useClass<span class="token operator">:</span>CatsService
  <span class="token punctuation">}</span>
<span class="token punctuation">]</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>上述明确的将令牌 <code>CatsService</code> 与类 <code>CatsService</code> 关联起来。简写表示法只是为了简化最常见的用例，其中令牌用于<strong>同名类</strong>的实例。</p><h3 id="值提供者" tabindex="-1"><a class="header-anchor" href="#值提供者" aria-hidden="true">#</a> 值提供者</h3><p><code>useValue</code> 语法对于注入常量值、将外部库放入 <code>Nest</code> 容器或使用模拟对象替换实际实现。假设强制 <code>Nest</code> 使用 <code>CatsService</code> 进行测试。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span>CatsService<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./cats.service&#39;</span>

<span class="token keyword">const</span> mockCatsService <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  providers<span class="token operator">:</span><span class="token punctuation">[</span><span class="token punctuation">{</span>
    provider<span class="token operator">:</span>CatsService<span class="token punctuation">,</span>
    useValue<span class="token operator">:</span>mockCatsService
  <span class="token punctuation">}</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code>CatsService</code> 令牌将解析为 <code>mockCatsService</code> 模拟对象。useValue 需要一个值，它与要替换的 CatsService 类具有相同的接口。由于 TypScript 的结构类型化，可以使用任何具有兼容接口的对象，包括文本对象或用 new 实例化的对象。</p><h3 id="非类提供者" tabindex="-1"><a class="header-anchor" href="#非类提供者" aria-hidden="true">#</a> 非类提供者</h3><p>之前示例均已类名作为提供者标记（providers 数组中列出的提供者中的 provider 属性值）。这与基于构造函数的注入所使用的标准模式匹配，其中令牌也是类名。可以灵活使用字符串或符号作为令牌。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span>connection<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./connection&#39;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  providers<span class="token operator">:</span><span class="token punctuation">[</span>
    <span class="token punctuation">{</span>
      provider<span class="token operator">:</span><span class="token string">&#39;CONNECTION&#39;</span><span class="token punctuation">,</span>
      useValue<span class="token operator">:</span>connection
    <span class="token punctuation">}</span>
  <span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>将字符串值令牌（<code>&#39;CONNECTION&#39;</code>）与外部文件导入的已存在链接对象相关联。</p><div class="custom-container danger"><p class="custom-container-title">警告</p><p>除了使用字符串作为令牌之外，还可以使用 JavaScript Symbol</p></div><h3 id="类提供者-useclass" tabindex="-1"><a class="header-anchor" href="#类提供者-useclass" aria-hidden="true">#</a> 类提供者（useClass）</h3><p><code>useClass</code> 语法允许动态确定令牌应解析为的类。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">const</span> configServiceProvider <span class="token operator">=</span> <span class="token punctuation">{</span>
  provide<span class="token operator">:</span>ConfigService<span class="token punctuation">,</span>
  useClass<span class="token operator">:</span>process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">NODE_ENV</span> <span class="token operator">===</span> <span class="token string">&#39;development&#39;</span>
    <span class="token operator">?</span> DevelopmentConfigService
    <span class="token operator">:</span> ProductionConfigService
<span class="token punctuation">}</span>
<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  provides<span class="token operator">:</span><span class="token punctuation">[</span>
    configServiceProvider
  <span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>使用 <code>ConfigService</code> 类名称作为令牌。对于任何依赖 <code>ConfigService</code> 的类，Nest 都会注入提供的类的实例（<code>DevelopmentConfigService</code> 或 <code>ProductionConfigService</code>）,该实例将覆盖在其他地方以声明的任何默认实现（例如：<code>@Injectable()</code> 装饰声明的 ConfigService）</p><h3 id="工厂提供者-usefactory" tabindex="-1"><a class="header-anchor" href="#工厂提供者-usefactory" aria-hidden="true">#</a> 工厂提供者（useFactory）</h3><p><code>useFactory</code> 语法允许动态创建提供程序。工厂函数的返回实际的 <code>provider</code>。工厂功能可以根据需要简单或复杂。一个简单的工厂可能不依赖于任何其他的提供者。更复杂的工厂可以自己注入它需要的其他提供者来计算结果。对于后一种情况，工厂提供程序语法有一对相关的机制：</p><ol><li>工厂函数可以接受（可选）参数。</li><li><code>inject</code> 属性接受一个提供者数组，在实例化过程中，Nest 将解析该数组并将其作为参数传递给工厂函数。这两个列表应该是相关的：Nest 将从 inject 列表中以相同的顺序将实例作为参数传递给工厂函数。</li></ol><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">const</span> connectionFactory <span class="token operator">=</span> <span class="token punctuation">{</span>
  provider<span class="token operator">:</span><span class="token string">&#39;CONNECTION&#39;</span><span class="token punctuation">,</span>
  <span class="token function-variable function">useFactory</span><span class="token operator">:</span><span class="token punctuation">(</span>optionsProvider<span class="token operator">:</span>OptionsProvider<span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
    <span class="token keyword">const</span> options <span class="token operator">=</span> <span class="token function">optionsProvider</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">DatabaseConnection</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  inject<span class="token operator">:</span><span class="token punctuation">[</span>OptionsProvider<span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  providers<span class="token operator">:</span><span class="token punctuation">[</span>connectionFactory<span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="别名提供者-useexisting" tabindex="-1"><a class="header-anchor" href="#别名提供者-useexisting" aria-hidden="true">#</a> 别名提供者（useExisting）</h3><p><code>useExisting</code> 语法允许为现有的提供程序创建别名。这将创建两种访问同一提供者的方法。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token decorator"><span class="token at operator">@</span><span class="token function">Injectable</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">class</span> <span class="token class-name">LoggrerService</span><span class="token punctuation">{</span><span class="token punctuation">}</span>

<span class="token keyword">const</span> loggerAliasProvider <span class="token operator">=</span> <span class="token punctuation">{</span>
  provider<span class="token operator">:</span><span class="token string">&#39;AliaseLoggerService&#39;</span><span class="token punctuation">,</span>
  useExisting<span class="token operator">:</span>LoggrerService
<span class="token punctuation">}</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  providers<span class="token operator">:</span><span class="token punctuation">[</span>LoggrerService<span class="token punctuation">,</span>loggerAliasProvider<span class="token punctuation">]</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="非服务提供者" tabindex="-1"><a class="header-anchor" href="#非服务提供者" aria-hidden="true">#</a> 非服务提供者</h3><p>提供者经常提供服务，但他们并不限于这种用途。提供者可以提供任何值。例如，提供程序可以根据当前环境提供配置对象数组，如下所示:</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">const</span> configFactory <span class="token operator">=</span> <span class="token punctuation">{</span>
  provide<span class="token operator">:</span> <span class="token string">&#39;CONFIG&#39;</span><span class="token punctuation">,</span>
  <span class="token function-variable function">useFactory</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">NODE_ENV</span> <span class="token operator">===</span> <span class="token string">&#39;development&#39;</span>
      <span class="token operator">?</span> devConfig
      <span class="token operator">:</span> prodConfig<span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  providers<span class="token operator">:</span> <span class="token punctuation">[</span>configFactory<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="导出自定义提供者" tabindex="-1"><a class="header-anchor" href="#导出自定义提供者" aria-hidden="true">#</a> 导出自定义提供者</h3><p>与任何提供程序一样，自定义提供程序的作用域仅限于其声明模块。要使它对其他模块可见，必须导出它。要导出自定义提供程序，我们可以使用其令牌或完整的提供程序对象。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">const</span> connectionFactory <span class="token operator">=</span> <span class="token punctuation">{</span>
  provide<span class="token operator">:</span> <span class="token string">&#39;CONNECTION&#39;</span><span class="token punctuation">,</span>
  <span class="token function-variable function">useFactory</span><span class="token operator">:</span> <span class="token punctuation">(</span>optionsProvider<span class="token operator">:</span> OptionsProvider<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> options <span class="token operator">=</span> optionsProvider<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">DatabaseConnection</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  inject<span class="token operator">:</span> <span class="token punctuation">[</span>OptionsProvider<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 以下示例显示了使用 token </span>
<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  providers<span class="token operator">:</span> <span class="token punctuation">[</span>connectionFactory<span class="token punctuation">]</span><span class="token punctuation">,</span>
  exports<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&#39;CONNECTION&#39;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token comment">// 使用整个对象</span>
<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  providers<span class="token operator">:</span> <span class="token punctuation">[</span>connectionFactory<span class="token punctuation">]</span><span class="token punctuation">,</span>
  exports<span class="token operator">:</span> <span class="token punctuation">[</span>connectionFactory<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="异步提供者" tabindex="-1"><a class="header-anchor" href="#异步提供者" aria-hidden="true">#</a> 异步提供者</h2><p>在完成一些异步任务之前，应用程序必须等待启动状态, 例如，在与数据库的连接建立之前，您可能不希望开始接受请求。 在这种情况下你应该考虑使用异步 provider。</p><p>其语法是使用 useFactory 语法的 async/await。工厂返回一个承诺，工厂函数可以等待异步任务。在实例化依赖于(注入)这样一个提供程序的任何类之前，Nest将等待承诺的解决。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token punctuation">{</span>
  provide<span class="token operator">:</span> <span class="token string">&#39;ASYNC_CONNECTION&#39;</span><span class="token punctuation">,</span>
  <span class="token function-variable function">useFactory</span><span class="token operator">:</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> connection <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">createConnection</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> connection<span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>与任何其他提供程序一样，异步提供程序通过其令牌被注入到其他组件。在上面的示例中，您将使用结构@Inject(&#39;ASYNC_CONNECTION&#39;)。</p><h2 id="可选提供者" tabindex="-1"><a class="header-anchor" href="#可选提供者" aria-hidden="true">#</a> 可选提供者</h2><p>有时，可能需要解决一些依赖项。例如，类可能依赖于一个配置对象，但如果没有传递，则应使用默认值。在这种情况下，关联变为可选的， provider 不会因为缺少配置导致错误。</p><p>要指示 provider 是可选的，在 constructor 的参数中使用 @Optional() 装饰器。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> Injectable<span class="token punctuation">,</span> Optional<span class="token punctuation">,</span> Inject <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;@nestjs/common&#39;</span><span class="token punctuation">;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Injectable</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">HttpService<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span></span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span>
    <span class="token decorator"><span class="token at operator">@</span><span class="token function">Optional</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token decorator"><span class="token at operator">@</span><span class="token function">Inject</span></span><span class="token punctuation">(</span><span class="token string">&#39;HTTP_OPTIONS&#39;</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token keyword">readonly</span> httpClient<span class="token operator">:</span> <span class="token constant">T</span>
  <span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="基于属性的注入" tabindex="-1"><a class="header-anchor" href="#基于属性的注入" aria-hidden="true">#</a> 基于属性的注入</h2><p>可以在属性上使用 @Inject() 装饰器。</p><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> Injectable<span class="token punctuation">,</span> Inject <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;@nestjs/common&#39;</span><span class="token punctuation">;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Injectable</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">HttpService<span class="token operator">&lt;</span><span class="token constant">T</span><span class="token operator">&gt;</span></span> <span class="token punctuation">{</span>
  <span class="token decorator"><span class="token at operator">@</span><span class="token function">Inject</span></span><span class="token punctuation">(</span><span class="token string">&#39;HTTP_OPTIONS&#39;</span><span class="token punctuation">)</span>
  <span class="token keyword">private</span> <span class="token keyword">readonly</span> httpClient<span class="token operator">:</span> <span class="token constant">T</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container danger"><p class="custom-container-title">警告</p><p>如果您的类没有扩展其他提供者，你应该总是使用基于<strong>构造函数</strong>的注入。</p></div><h2 id="注册提供者" tabindex="-1"><a class="header-anchor" href="#注册提供者" aria-hidden="true">#</a> 注册提供者</h2><div class="language-typescript line-numbers-mode" data-ext="ts"><pre class="language-typescript"><code><span class="token doc-comment comment">/**
 * app.module.ts
 */</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> Module <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;@nestjs/common&#39;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> CatsController <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./cats/cats.controller&#39;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> CatsService <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#39;./cats/cats.service&#39;</span><span class="token punctuation">;</span>

<span class="token decorator"><span class="token at operator">@</span><span class="token function">Module</span></span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  controllers<span class="token operator">:</span> <span class="token punctuation">[</span>CatsController<span class="token punctuation">]</span><span class="token punctuation">,</span>
  providers<span class="token operator">:</span> <span class="token punctuation">[</span>CatsService<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">AppModule</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>完整模块的目录结构：</p><div class="language-text line-numbers-mode" data-ext="text"><pre class="language-text"><code>src
├── cats
│    ├──dto
│    │   └──create-cat.dto.ts
│    ├── interfaces
│    │       └──cat.interface.ts
│    ├──cats.service.ts
│    └──cats.controller.ts
├──app.module.ts
└──main.ts

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></div><!----><footer class="page-meta"><!----><div class="meta-item update-time"><span class="label">上次编辑于: </span><!----></div><!----></footer><!----><!----><!----><!--]--></main><!--]--><!----><!--]--></div><!--]--><!----><!--]--></div>
    <script type="module" src="/doc/assets/app.41440b49.js" defer></script>
  </body>
</html>
